package com.demo.util;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author bfyrd
 * description 发送HTTP请求的工具类
 */
public final class HttpUtil {

    private static final Logger LOGGER = LogManager.getLogger(HttpUtil.class);

    /**
     * 字符集: UTF-8
     */
    public static final String CHARSET_UTF_8 = "UTF-8";

    /**
     * 发送get请求并且获取响应内容
     *
     * @param url 发送请求的地址
     * @return 将响应的内容以字符串的格式返回
     */
    public static String get(final String url) {
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        CloseableHttpResponse response = null;
        try {
            HttpGet httpget = new HttpGet(url);
            // 执行get请求.
            response = httpclient.execute(httpget);
            // 获取响应实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity);
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            StreamUtil.closeStream(httpclient, response);
        }
        return null;
    }


    public static String postJson(final String url, final String json) {
        return postJsonWithHeader(url, null, json);
    }


    public static String postJsonWithHeader(final String url, final Map<String, String> header, final String json, RequestConfig config) {
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            // 创建httpPost
            HttpPost httppost = new HttpPost(url);
            // 判断是否需要设置代理
            if (config != null) {
                HttpHost proxy = config.getProxy();
                if (proxy != null) {
                    LOGGER.warn("use proxy to send request, proxy:" + proxy.toHostString() + "url: " + url);
                }
                httppost.setConfig(config);
            }
            // 设置请求头
            if (header != null && header.size() > 0) {
                for (String key : header.keySet()) {
                    httppost.setHeader(key, header.get(key));
                }
            }
            //设置实体内容的格式, 如果传送"application/xml"格式，选择ContentType.APPLICATION_XML
            if (StringUtils.isNotBlank(json)) {
                StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
                httppost.setEntity(entity);
            } else {
                LOGGER.warn("The POST request url: " + url + ", param is null, Are you sure?");
            }
            response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                return EntityUtils.toString(resEntity, CHARSET_UTF_8);
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            StreamUtil.closeStream(httpclient, response);
        }
        return null;
    }

    /**
     * 发送POST请求, 参数以JSON格式传递
     *
     * @param url    请求的地址
     * @param header 请求头中的参数
     * @param json   请求的JSON格式参数
     * @return 返回响应的内容
     */
    public static String postJsonWithHeader(final String url, final Map<String, String> header, final String json) {
        return postJsonWithHeader(url, header, json, null);
    }


    public static String postForm(final String url, final Map<String, Object> param) {
        return postFormWithHeader(url, null, param);
    }

    /**
     * 发送POST请求, 以表单的方式提交
     *
     * @param url    发送请求的地址
     * @param header 请求头参数
     * @param param  表单中的参数
     * @return 请求的返回信息
     */
    public static String postFormWithHeader(final String url, final Map<String, String> header, final Map<String, Object> param) {
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            HttpPost httppost = new HttpPost(url);
            if (header != null && header.size() > 0) {
                for (String key : header.keySet()) {
                    httppost.setHeader(key, header.get(key));
                }
            }
            // 创建参数队列,进行参数组装
            List<NameValuePair> paramList = new ArrayList<>();
            if (param != null && param.size() > 0) {
                for (String key : param.keySet()) {
                    if (param.get(key) != null) {
                        paramList.add(new BasicNameValuePair(key, param.get(key).toString()));
                    } else {
                        LOGGER.warn("The POST Request url : " + url + ",  Their is a Param " + key + "is null, Are you sure?");
                    }
                }
            }
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, CHARSET_UTF_8);
            httppost.setEntity(entity);
            response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                return EntityUtils.toString(resEntity, CHARSET_UTF_8);
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            StreamUtil.closeStream(httpclient, response);
        }
        return null;
    }
}

